package org.gas.barapraja.handler.validator;

import org.apache.log4j.Logger;
import org.gas.barapraja.db.dao.AccountDao;
import org.gas.barapraja.db.entity.Account;
import org.gas.barapraja.db.entity.Token;

import com.logica.smpp.Data;
import com.logica.smpp.pdu.BindRequest;
import com.logica.smpp.pdu.Request;
import com.logica.smpp.pdu.SubmitMultiSM;
import com.logica.smpp.pdu.SubmitSM;

public class RequestValidatorImpl implements RequestValidator {

	private static final Logger logger=Logger.getLogger(RequestValidatorImpl.class);
	
	private String systemId;
	
	private int numOfMsg;
	
	private AccountDao accountDao;
	
	public int validate(Request request) {
		int valid=0;
		if(request instanceof BindRequest)
			valid=validateBind((BindRequest) request);
		else if(request instanceof SubmitSM)
			valid=validateSingle((SubmitSM)request);
		else if(request instanceof SubmitMultiSM)
			valid=validateMulti((SubmitMultiSM)request);
		else
			valid=0;
		return valid;
	}
	
	private int validateBind(BindRequest request){
		int status=Data.ESME_ROK;
		logger.info("validating bind request...");
		Account account=accountDao.findBySystemId(request.getSystemId());
		if(account!=null){
			String passwd=account.getPassword();
			if(passwd!=null){
				if(!request.getPassword().equals(passwd)){
					status=Data.ESME_RINVPASWD;
					logger.debug("invalid password for id: "+request.getSystemId());
				}else{
					systemId=request.getSystemId();
					logger.info("system id: "+systemId+" authenticated");
				}
			}else{
				status=Data.ESME_RINVPASWD;
				logger.debug("password not found for id: "+request.getSystemId());
			}
		}else{
			status=Data.ESME_RINVSYSID;
			logger.debug("failed to authenticated id:"+request.getSystemId()+" [user not found]");
		}
		return status;
	}
	
	private int validateSingle(SubmitSM submitSM){
		logger.info("validating submit single message request...");
		Account account=accountDao.findByNumber(submitSM.getSourceAddr().getAddress());
		Token token=account.getToken();
		int code=0;
		if(token!=null){
			int sumOfToken=token.getTokenValue();
			if(sumOfToken<=0){
				logger.debug("token is not enough to send message");
				code=TOKEN_NOT_OK;
			}else{
				logger.debug("token status ok, ready to send message");
				code=TOKEN_OK;
			}
		}else{
			code=TOKEN_NOT_OK;
		}
		return code;
	}
	
	private int validateMulti(SubmitMultiSM multiSM){
		Account account=accountDao.findByNumber(multiSM.getSourceAddr().getAddress());
		Token token=account.getToken();
		int code=0;
		if(token!=null){
			int sumOfToken=token.getTokenValue();
			if(multiSM.getNumberOfDests()>sumOfToken){
				logger.debug("token is not enough to send multiple messages, token: "+sumOfToken+
						" msg(s) to send: "+multiSM.getNumberOfDests());
				code=TOKEN_NOT_OK;
			}else{
				numOfMsg=sumOfToken-multiSM.getNumberOfDests();
				logger.debug("ready to send multiple message. number of message to send: "+numOfMsg);
				code=TOKEN_OK;
			}
		}else{
			code=TOKEN_NOT_OK;
		}
		return code;
	}

	public String getSystemId() {
		return systemId;
	}

	public int getNumOfMsg() {
		return numOfMsg;
	}
	
	

}
